package webapp.web.servlet;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

import com.alibaba.fastjson.JSONArray;

import webapp.web.util.MD5;

/**
 * Servlet implementation class watsonsServlet
 */
@WebServlet("/watsonsServlet")
public class watsonsServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	// 密码本
	final static String[] PASSWORD_BOOK = { "3", "4", "5", "6", "7", "9", "A",
			"C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q",
			"R", "S", "T", "W", "X", "Y" };
	// 混淆字符
	final static char[] MIX_CHAR = { '0', '1', '2', '8', 'B', 'I', 'O', 'U',
			'V', 'Z' };
	// 企业密钥
	final static String ENTERPRISE_KEY = "469CD-NDV8T-B6YVG-3T2P8-W4YQP";

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public watsonsServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String action = request.getParameter("action");
		long startTime = System.currentTimeMillis();
		if (action.equals("1")) { // 返回1w数据
			JSONArray array = new JSONArray();
			array = this.getJSONCode(10000);
			response.getWriter().print(array);
		} else if (action.equals("2")) {// 返回100w并保存成excel文件
			String fileName = "code"; // 文件名称
			String path = request.getSession().getServletContext()
					.getRealPath("/")
					+ fileName + ".xls";
			String[] array = new String[1000000];
			array = this.getCode(1000000);
			OutputStream os = response.getOutputStream();
			this.writeExcel(path, array, os);// 参数：路径，文件名，json文件
		}
		long endTime = System.currentTimeMillis();
		System.out.println("程序运行时间：" + (endTime - startTime) + "ms");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}

	public String[] getCode(int nums) {
		String[] array = new String[1000000];
		for (int num = 0; num < nums; num++) {
			int val = num + 1;
			String getStr = "" + val;
			// if (getStr.length() < 8) { // 长度小于8，补够8位数，"119527"->"10119527"
			getStr = "1" + String.format("%07d", Integer.parseInt(getStr));
			// }
			int getInt = Integer.parseInt(getStr);
			int pblength = PASSWORD_BOOK.length;
			int[] pbInt = new int[6];// 密码本下标数组
			for (int i = 0; i < pbInt.length; i++) { // 密码本加密
				pbInt[i] = getInt % pblength;
				getInt = getInt / pblength;
			}
			String pbStr = ""; // 密码字符串
			for (int i = pbInt.length - 1; i >= 0; i--) {
				pbStr += PASSWORD_BOOK[pbInt[i]]; // 密码本密码赋值
			}
			String md5Str = "";
			md5Str = new MD5().getMD5Str(pbStr + ENTERPRISE_KEY); // MD5加密
			md5Str = md5Str.toUpperCase();// 加密完转换大写，方便匹配混淆大写字符
			char[] md5Arr = md5Str.toCharArray();// 转换字符数组，匹配，取6个值
			String charStr = "";// 抽取字符完成存放的字符串
			boolean mix = false;// 是否包含混淆字符，false为不包含，true为包含
			for (int i = 0; i < md5Arr.length; i++) {
				for (int j = 0; j < MIX_CHAR.length; j++) {
					mix = false;
					if (md5Arr[i] == MIX_CHAR[j]) {
						mix = true;
						break;
					}
				}
				if (!mix) {
					charStr += md5Arr[i];
					if (charStr.length() == 6) {
						break;
					}
				}
			}
			array[num] = (pbStr + charStr);
		}
		return array;
	}

	public JSONArray getJSONCode(int nums) {
		JSONArray array = new JSONArray();
		for (int num = 0; num < nums; num++) {
			int val = num + 1;
			String getStr = "" + val;
			// if (getStr.length() < 8) { // 长度小于8，补够8位数，"119527"->"10119527"
			getStr = "1" + String.format("%07d", Integer.parseInt(getStr));
			// }
			int getInt = Integer.parseInt(getStr);
			int pblength = PASSWORD_BOOK.length;
			int[] pbInt = new int[6];// 密码本下标数组
			String[] pbStrArr = new String[6];
			for (int i = pbInt.length - 1; i >= 0; i--) { // 密码本加密
				pbInt[i] = getInt % pblength;
				getInt = getInt / pblength;
				pbStrArr[i] = PASSWORD_BOOK[pbInt[i]];
			}
			String pbStr = pbStrArr.toString(); // 密码字符串
			String md5Str = "";
			md5Str = new MD5().getMD5Str(pbStr + ENTERPRISE_KEY); // MD5加密
			md5Str = md5Str.toUpperCase();// 加密完转换大写，方便匹配混淆大写字符
			char[] md5Arr = md5Str.toCharArray();// 转换字符数组，匹配，取6个值
			String charStr = "";// 抽取字符完成存放的字符串
			boolean mix = false;// 是否包含混淆字符，false为不包含，true为包含
			for (int i = 0; i < md5Arr.length; i++) {
				for (int j = 0; j < MIX_CHAR.length; j++) {
					mix = false;
					if (md5Arr[i] == MIX_CHAR[j]) {
						mix = true;
						break;
					}
				}
				if (!mix) {
					charStr += md5Arr[i];
					if (charStr.length() == 6) {
						break;
					}
				}
			}
			array.add(pbStr + charStr);
		}
		return array;
	}

	/*
	 * // 给定路径与Json文件，存储到硬盘 public void writeTxt(String path, JSONArray json) {
	 * BufferedWriter writer = null; File file = new File(path + fileName +
	 * ".txt"); // 如果文件不存在，则新建一个 if (!file.exists()) { try {
	 * file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } }
	 * // 写入 try { writer = new BufferedWriter(new FileWriter(file));
	 * writer.write(json.toString()); } catch (IOException e) {
	 * e.printStackTrace(); } finally { try { if (writer != null) {
	 * writer.close(); } } catch (IOException e) { e.printStackTrace(); } } //
	 * System.out.println("文件写入成功！"); }
	 */

	public void writeExcel(String path, String[] array, OutputStream os) {
		// 创建工作薄
		WritableWorkbook workbook;
		try {
			workbook = Workbook.createWorkbook(new File(path));
			// 创建新的一页
			int pages = (array.length - 1) / 60000 + 1;
			for (int s = 0; s < pages; s++) {
				WritableSheet sheet = workbook.createSheet("Sheet" + s, s);
				for (int i = s * 60000; i < (s + 1) * 60000; i++) {
					String jsonStr = array[i];
					Label label = new Label(0, i % 60000, jsonStr);
					sheet.addCell(label);
					if (i + 1 == array.length) {
						break;
					}
				}
			}
			// 把创建的内容写入到输出流中，并关闭输出流
			workbook.write();
			workbook.close();
			os.close();
		} catch (IOException | WriteException e) {
			e.printStackTrace();
		}

	}
}
